/**
  ******************************************************************************
  * @file    stm32f1xx_flash.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  *
  * COPYRIGHT(c) 2016 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include "stm32f1xx_hal.h"
#include "stm32f1xx.h"
#include "stm32f1xx_flash.h"

/* USER CODE BEGIN 0 */
uint8_t gFlashBuf[FLASH_PAGE_SIZE];
static void Flash_ReadNHalfWord(uint32_t addr, uint16_t len, uint8_t *buf);

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/

/**************************************************************************************
  * @brief  Change System Information
  * @param  offset:  address=base+offset
  * @param  len:     lenght of change data
  * @param  Data:    
  * 
  * @retval HAL_StatusTypeDef HAL Status
**************************************************************************************/
void Flash_ChangeSystemInformation(uint16_t offset, uint16_t len, uint8_t *buf)
{
  uint16_t i;
  uint32_t tmpValue;
  uint32_t tmpAddr=SYSTEM_INFORMATION_BASE_ADDR;
  FLASH_EraseInitTypeDef pEraseInit;
  uint32_t PageError;
  
  if(len > FLASH_PAGE_SIZE-offset)return;
  Flash_ReadNHalfWord(tmpAddr, FLASH_PAGE_SIZE, gFlashBuf);
  HAL_FLASH_Unlock();
  pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  pEraseInit.NbPages = 1;
  pEraseInit.PageAddress = tmpAddr;
  HAL_FLASHEx_Erase(&pEraseInit, &PageError);
  memcpy(gFlashBuf+offset, buf, len);
  
  for(i = 0; i < FLASH_PAGE_SIZE/4; i++)
  {
    tmpValue = BUILD_UINT32(gFlashBuf[4*i],gFlashBuf[4*i+1],gFlashBuf[4*i+2],gFlashBuf[4*i+3]);
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, tmpAddr, tmpValue);
    tmpAddr += 4;
  }
  HAL_FLASH_Lock();
}
/**************************************************************************************
  * @brief  Read System Information
  * @param  offset:  address=base+offset
  * @param  len:     lenght of change data
  * @param  Data:    
  * 
  * @retval HAL_StatusTypeDef HAL Status
**************************************************************************************/
void Flash_ReadSystemInformation(uint16_t offset, uint16_t len, uint8_t *buf)
{
  uint32_t tmpAddr = SYSTEM_INFORMATION_BASE_ADDR;
  
  Flash_ReadNHalfWord(tmpAddr, FLASH_PAGE_SIZE, gFlashBuf);
  memcpy(buf, gFlashBuf+offset, len);
}
/**************************************************************************************
  * @brief  Restore factory
  * 
  * @retval HAL_StatusTypeDef HAL Status
**************************************************************************************/
uint8_t Flash_RestoreToFactory(void)
{
  uint8_t status;
  FLASH_EraseInitTypeDef pEraseInit;
  uint32_t PageError;

  HAL_FLASH_Unlock();
  pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  pEraseInit.NbPages = 1;
  pEraseInit.PageAddress = SYSTEM_INFORMATION_BASE_ADDR;
  status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
  HAL_FLASH_Lock();
  return status;
}
/**************************************************************************************
  * @brief  Read data from flash
  * @param  TypeProgram:  Indicate the way to program at a specified address.
  *                       This parameter can be a value of @ref FLASH_Type_Program
  * @param  Address:      Specifies the address to be programmed.
  * @param  Data:         Specifies the data to be programmed
  * 
  * @retval HAL_StatusTypeDef HAL Status
**************************************************************************************/
static void Flash_ReadNHalfWord(uint32_t addr, uint16_t len, uint8_t *buf)
{
  uint16_t i;
  uint32_t tmpAddr=addr;
  uint16_t tmpValue;
  
  for(i = 0; i < len/2; i++)
  {
    tmpValue = *(__IO uint16_t*)tmpAddr;
    tmpAddr += 2;
    *buf++ = tmpValue;
    *buf++ = tmpValue>>8;
  }
}
/******************************************************************************/
/*            Cortex-M0+ Processor Interruption and Exception Handlers         */ 
/******************************************************************************/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
